package wenjie.chen.transfer.dao;

import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Log4j
@Transactional
@Component
@RequiredArgsConstructor
public class AccountDao {
    @NonNull
    private final JdbcTemplate jdbcTemplate;

    public Double findAmountBy(String accountId) {
        String query = "SELECT amount FROM account WHERE id = ?";
        return this.jdbcTemplate.queryForObject(query, new Object[]{accountId}, Double.class);
    }

    public Double findFrozenBy(String accountId) {
        String query = "SELECT frozen FROM account WHERE id = ?";
        return this.jdbcTemplate.queryForObject(query, new Object[]{accountId}, Double.class);
    }

    public void tryDecreaseAmount(String accountId, double amount) {
        int value = this.jdbcTemplate.update(
            "UPDATE account SET amount = amount - ?, frozen = frozen + ? WHERE id = ?", amount, amount, accountId);
        if (value != 1) {
            throw new IllegalStateException("ERROR!");
        }
        log.debug(String.format("done decrease: accountId= %s, amount= %7.2f%n", accountId, amount));
    }

    public void confirmDecreaseAmount(String accountId, double amount) {
        int value = this.jdbcTemplate.update(
            "UPDATE account SET frozen = frozen - ? WHERE id = ?", amount, accountId);
        if (value != 1) {
            throw new IllegalStateException("ERROR!");
        }
        log.debug(String.format("done decrease: accountId= %s, amount= %7.2f%n", accountId, amount));
    }

    public void cancelDecreaseAmount(String accountId, double amount) {
        int value = this.jdbcTemplate.update(
            "UPDATE account SET amount = amount + ?, frozen = frozen - ? WHERE id = ?", amount, amount, accountId);
        if (value != 1) {
            throw new IllegalStateException("ERROR!");
        }
        log.debug(String.format("undo decrease: accountId= %s, amount= %7.2f%n", accountId, amount));
    }
}
